#include "ObjectRegistry.h"
#include "../exceptions/ObjectNotFoundException.h"
#include <QDebug>
#include <QObject>
#include <QString>
#include <memory>
#include <shared_mutex>


bool ObjectRegistry::registerObject(QObject *obj, const QString &objectId) {
  if (!obj || objectId.isEmpty()) {
    return false;
  }

  // 检查对象或ID是否已存在
  if (containsObject(obj) || containsObject(objectId)) {
    return false;
  }

  // 添加写锁
  std::unique_lock<std::shared_mutex> lock(m_mutex);

  // 注册对象
  m_objects[objectId] = obj;
  m_objectIds[obj] = objectId;

  return true;
}

bool ObjectRegistry::unregisterObject(const QString &objectId) {
  if (objectId.isEmpty()) {
    return false;
  }

  // 添加写锁
  std::unique_lock<std::shared_mutex> lock(m_mutex);

  auto it = m_objects.find(objectId);
  if (it == m_objects.end()) {
    return false;
  }

  QObject *obj = it->second;
  m_objects.erase(it);
  m_objectIds.erase(obj);

  return true;
}

QObject *ObjectRegistry::getObject(const QString &objectId) const {
  if (objectId.isEmpty()) {
    return nullptr;
  }

  // 添加读锁
  std::shared_lock<std::shared_mutex> lock(m_mutex);

  auto it = m_objects.find(objectId);
  if (it == m_objects.end()) {
    return nullptr;
  }

  return it->second;
}

QString ObjectRegistry::getObjectId(QObject *obj) const {
  if (!obj) {
    return QString();
  }

  // 添加读锁
  std::shared_lock<std::shared_mutex> lock(m_mutex);

  auto it = m_objectIds.find(obj);
  if (it == m_objectIds.end()) {
    return QString();
  }

  return it->second;
}

bool ObjectRegistry::containsObject(const QString &objectId) const {
  if (objectId.isEmpty()) {
    return false;
  }

  // 添加读锁
  std::shared_lock<std::shared_mutex> lock(m_mutex);

  return m_objects.find(objectId) != m_objects.end();
}

bool ObjectRegistry::containsObject(QObject *obj) const {
  if (!obj) {
    return false;
  }

  // 添加读锁
  std::shared_lock<std::shared_mutex> lock(m_mutex);

  return m_objectIds.find(obj) != m_objectIds.end();
}

std::vector<QString> ObjectRegistry::getAllObjectIds() const {
  // 添加读锁
  std::shared_lock<std::shared_mutex> lock(m_mutex);

  std::vector<QString> ids;
  ids.reserve(m_objects.size());

  for (const auto &pair : m_objects) {
    ids.push_back(pair.first);
  }

  return ids;
}